﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Threading;
using System.Threading;

namespace JAAF.UI.WPF
{
    public abstract class RichClientApplication : UIApplication
    {
        private DependencyObject m_oShellControl;

        /// <summary>
        /// This method is called by the framework just after the <see cref="UIApplication.CreateShell"/>
        /// method has returned succesfully with a newlly created application <see cref="IShell">shell</see>.
        /// It gives subclasses the chance to perform additional initialization on the <see cref="IShell">shell</see>
        /// just before it is displayed.
        /// </summary>
        protected override void OnAfterShellCreated()
        {
            base.OnAfterShellCreated();

            m_oShellControl = this.Shell as DependencyObject;
        }


        /// <summary>
        /// Displays a dialog window with a question with two answers, Yes an No.
        /// </summary>
        /// <param name="_sMessage">The question to display to the user</param>
        /// <param name="_sTitle">The title of the dialog</param>
        /// <param name="_bDefaultResponse">Defines the default response for the dialog.</param>
        /// <returns>
        /// True if the selected response is Yes and false if the response is No
        /// </returns>
        public override bool DisplayYesNoQuestion(string _sMessage, string _sTitle = null, bool _bDefaultResponse = true)
        {
            MessageBoxResult eResponse;

            Func<bool> inv = delegate
            {
                eResponse = MessageBox.Show(_sMessage,
                                        !string.IsNullOrWhiteSpace(_sTitle) ? _sTitle : this.Title,
                                        MessageBoxButton.YesNo,
                                        MessageBoxImage.Question,
                                        _bDefaultResponse ?
                                        MessageBoxResult.Yes : MessageBoxResult.No);

                if (eResponse == MessageBoxResult.Yes)
                    return true;
                else
                    return false;
            };

            if (m_oShellControl.Dispatcher.Thread != Thread.CurrentThread)
            {
                return (bool)m_oShellControl.Dispatcher.Invoke(inv);
            }
            else
            {
                return inv();
            }
        }

        /// <summary>
        /// Displays an error message based on a given <see cref="System.Exception"/>.
        /// </summary>
        /// <param name="_sMessage">The error message to display</param>
        /// <param name="_sTitle">The title of the dialog window.</param>
        public override void DisplayErrorMessage(string _sMessage, string _sTitle = null)
        {
            Action inv = delegate()
            {
                MessageBox.Show(_sMessage,
                                !string.IsNullOrWhiteSpace(_sTitle) ? _sTitle : this.Title,
                                MessageBoxButton.OK,
                                MessageBoxImage.Error);
            };

            if (m_oShellControl.Dispatcher.Thread != Thread.CurrentThread)
            {
                m_oShellControl.Dispatcher.Invoke(inv);
            }
            else
            {
                inv();
            }
        }

        /// <summary>
        /// Displays an error message based on a given <see cref="System.Exception"/>.
        /// </summary>
        /// <param name="_exc">The exception to display.</param>
        /// <param name="_sTitle">The title of the dialog window</param>
        public override void DisplayException(Exception _exc, string _sTitle = null)
        {
            Action inv = delegate()
            {
                MessageBox.Show(_exc.Message,
                    !string.IsNullOrWhiteSpace(_sTitle) ? _sTitle : this.Title,
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
            };

            if (m_oShellControl.Dispatcher.Thread != Thread.CurrentThread)
            {
                m_oShellControl.Dispatcher.Invoke(inv);
            }
            else
            {
                inv();
            }

        }

        /// <summary>
        /// Displays an informational message to the user.
        /// </summary>
        /// <param name="_sMessage">The message to display.</param>
        /// <param name="_sTitle">The title of the dialog window</param>
        public override void DisplayInfo(string _sMessage, string _sTitle = null)
        {
            Action inv = delegate()
            {
                MessageBox.Show(_sMessage,
                                !string.IsNullOrWhiteSpace(_sTitle) ? _sTitle : this.Title,
                                MessageBoxButton.OK,
                                MessageBoxImage.Information);
            };

            if (m_oShellControl.Dispatcher.Thread != Thread.CurrentThread)
            {
                m_oShellControl.Dispatcher.Invoke(inv);
            }
            else
            {
                inv();
            }
        }

        /// <summary>
        /// Displays a warning dialog window to the user.
        /// </summary>
        /// <param name="_sMessage">The warning message to display</param>
        /// <param name="_sTitle">The title of the dialog window.</param>
        public override void DisplayWarning(string _sMessage, string _sTitle = null)
        {
            Action inv = delegate()
            {
                MessageBox.Show(_sMessage,
                    !string.IsNullOrWhiteSpace(_sTitle) ? _sTitle : this.Title,
                    MessageBoxButton.OK,
                    MessageBoxImage.Warning);
            };

            if (m_oShellControl.Dispatcher.Thread != Thread.CurrentThread)
            {
                m_oShellControl.Dispatcher.Invoke(inv);
            }
            else
            {
                inv();
            }
        }
    }
}
